import dash
from dash import dcc, html
import plotly.graph_objects as go
import pandas as pd
import json
import datetime

COLOR_SCHEME = {
    'background': '#0d1117',
    'card_bg': '#161b22',
    'primary': '#c9d1d9',
    'secondary': '#8b949e',
    'gas': '#ff7b72',     # 红色系
    'water': '#79c0ff',   # 蓝色系
    'temp': '#7ee787',    # 绿色系
    'progress': '#d2a8ff', # 紫色系
    'accent': '#1f6feb',   # 强调色
    'border': '#30363d'    # 边框色
}

def create_metric_card(title, color, items):
    """创建暗黑风格的指标卡片组件"""
    return html.Div(
        style={
            'background': COLOR_SCHEME['card_bg'],
            'padding': '1.5rem',
            'borderRadius': '8px',
            'border': f'1px solid {COLOR_SCHEME["border"]}',
            'position': 'relative',
            'overflow': 'hidden',
            'boxShadow': '0 8px 24px rgba(0,0,0,0.3)',
            'transition': 'transform 0.2s',
            ':hover': {
                'transform': 'translateY(-5px)'
            }
        },
        children=[
            # 装饰性光带
            html.Div(style={
                'position': 'absolute',
                'top': 0,
                'left': 0,
                'width': '4px',
                'height': '100%',
                'background': color,
                'borderRadius': '8px 0 0 8px'
            }),
            html.H3(
                title,
                style={
                    'color': color,
                    'marginBottom': '1.5rem',
                    'fontSize': '1.2rem',
                    'display': 'flex',
                    'alignItems': 'center',
                    'gap': '0.5rem'
                }
            ),
            *[html.Div(
                style={
                    'display': 'flex',
                    'justifyContent': 'space-between',
                    'marginBottom': '1rem',
                    'padding': '0.5rem',
                    'borderRadius': '6px',
                    ':hover': {
                        'background': '#1f6feb20'
                    }
                },
                children=[
                    html.Span(name, style={'color': COLOR_SCHEME['secondary'], 'fontSize': '0.95rem'}),
                    html.Span(value, style={'fontWeight': '600', 'color': COLOR_SCHEME['primary']})
                ]
            ) for name, value in items]
        ]
    )

def validate_data(df):
    """验证数据完整性"""
    required_columns = {
        '日期', '项目', '集团', '面积 (m²)',
        '日气耗量 (m³)', '累计气耗量 (m³)',
        '日水耗量 (m³)', '累计水耗量 (m³)',
        '室外温度 (°C)'
    }
    missing = required_columns - set(df.columns)
    if missing:
        raise KeyError(f"数据缺失关键字段: {missing}")


def calculate_metrics(df):
    """统一计算所有衍生指标"""
    # 供暖季定义（可根据实际调整）
    HEATING_START = datetime.datetime(2024, 11, 15)
    HEATING_END = datetime.datetime(2025, 3, 15)

    # 转换日期格式
    df['日期'] = pd.to_datetime(df['日期'])

    # 计算法定供暖天数
    df['法定已供暖天数'] = (HEATING_END - HEATING_START).days

    # 计算实际供暖天数
    df['已供暖天数'] = (df['日期'] - HEATING_START).dt.days.clip(lower=0)

    # 计算评分指标
    df['日气耗评价值'] = (df['日气耗量 (m³)'] / df['面积 (m²)']) * 121
    df['日水耗评价值'] = (df['日水耗量 (m³)'] / df['面积 (m²)']) * 121

    # 计算供暖进度
    df['供暖进度'] = (df['已供暖天数'] / df['法定已供暖天数']).clip(upper=1.0)

    return df


# 数据加载与预处理
def load_data():
    with open('data/供暖数据.json', 'r', encoding='utf-8') as f:
        raw_data = json.load(f)

    df = pd.DataFrame(raw_data)
    validate_data(df)
    df = calculate_metrics(df)
    return df


def create_timeline_chart(df):
    # 修改图表为暗黑风格
    fig = go.Figure(
        data=[
            go.Scatter(
                x=df['日期'],
                y=df['日气耗量 (m³)'],
                name='气耗量',
                line=dict(color=COLOR_SCHEME['gas'], width=2),
                mode='lines+markers',
                marker=dict(size=6, line=dict(width=1, color='black'))
            ),
            go.Scatter(
                x=df['日期'],
                y=df['日水耗量 (m³)'],
                name='水耗量',
                line=dict(color=COLOR_SCHEME['water'], width=2),
                mode='lines+markers',
                marker=dict(size=6, line=dict(width=1, color='black'))
            )
        ]
    )

    fig.update_layout(
        title='能源消耗趋势',
        plot_bgcolor=COLOR_SCHEME['card_bg'],
        paper_bgcolor=COLOR_SCHEME['card_bg'],
        font_color=COLOR_SCHEME['primary'],
        xaxis=dict(
            title='日期',
            gridcolor=COLOR_SCHEME['border'],
            linecolor=COLOR_SCHEME['border'],
            zerolinecolor=COLOR_SCHEME['border']
        ),
        yaxis=dict(
            title='消耗量 (m³)',
            gridcolor=COLOR_SCHEME['border'],
            linecolor=COLOR_SCHEME['border'],
            zerolinecolor=COLOR_SCHEME['border']
        ),
        legend=dict(
            orientation='h',
            yanchor='bottom',
            y=1.02,
            font=dict(color=COLOR_SCHEME['secondary'])
        ),
        hoverlabel=dict(
            bgcolor=COLOR_SCHEME['card_bg'],
            font_size=14,
            font_color=COLOR_SCHEME['primary']
        )
    )
    return fig


app = dash.Dash(__name__)
full_df = load_data()
current_data = full_df[full_df['日期'] == '2025-01-22'].iloc[0]
app.layout = html.Div(
    style={
        'backgroundColor': COLOR_SCHEME['background'],
        'padding': '2rem',
        'minHeight': '100vh',
        'fontFamily': 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
    },
    children=[
        html.Header(
            style={
                'textAlign': 'center',
                'marginBottom': '3rem',
                'position': 'relative',
                'paddingBottom': '1.5rem'
            },
            children=[
                html.Div(
                    style={
                        'position': 'absolute',
                        'bottom': 0,
                        'left': '50%',
                        'transform': 'translateX(-50%)',
                        'width': '120px',
                        'height': '3px',
                        'background': COLOR_SCHEME['accent'],
                        'borderRadius': '2px'
                    }
                ),
                html.H1(
                    '🌙 智慧供暖监控平台',
                    style={
                        'color': COLOR_SCHEME['primary'],
                        'marginBottom': '0.5rem',
                        'fontSize': '2.2rem',
                        'letterSpacing': '-0.5px'
                    }
                ),
                html.Div(
                    [
                        html.Span("📅", style={'color': COLOR_SCHEME['secondary']}),
                        html.Span(
                            f" 数据日期：{current_data['日期'].strftime('%Y-%m-%d')}",
                            style={'color': COLOR_SCHEME['secondary'], 'marginRight': '1.5rem'}
                        ),
                        html.Span("🏢", style={'color': COLOR_SCHEME['secondary']}),
                        html.Span(
                            f" 项目名称：{current_data['项目']}",
                            style={'color': COLOR_SCHEME['secondary']}
                        )
                    ],
                    style={'fontSize': '0.95rem'}
                )
            ]
        ),
        html.Div(
            style={
                'display': 'grid',
                'gridTemplateColumns': 'repeat(auto-fit, minmax(300px, 1fr))',
                'gap': '1.5rem',
                'marginBottom': '2rem'
            },
            children=[
                create_metric_card(
                    title='🔥 气耗指标',
                    color=COLOR_SCHEME['gas'],
                    items=[
                        ('当日消耗', f"{current_data['日气耗量 (m³)']:.1f} m³"),
                        ('累计消耗', f"{current_data['累计气耗量 (m³)']:.0f} m³"),
                        ('能效评分', f"{current_data['日气耗评价值']:.1f} 分")
                    ]
                ),
                create_metric_card(
                    title='💧 水耗指标',
                    color=COLOR_SCHEME['water'],
                    items=[
                        ('当日消耗', f"{current_data['日水耗量 (m³)']:.1f} m³"),
                        ('累计消耗', f"{current_data['累计水耗量 (m³)']:.0f} m³"),
                        ('能效评分', f"{current_data['日水耗评价值']:.1f} 分")
                    ]
                ),
                create_metric_card(
                    title='🌡️ 环境指标',
                    color=COLOR_SCHEME['temp'],
                    items=[
                        ('室外温度', f"{current_data['室外温度 (°C)']:.1f} °C"),
                        ('供暖天数', f"{current_data['已供暖天数']}/{current_data['法定已供暖天数']} 天"),
                        ('能耗成本', '0.79 元/m²')
                    ]
                )
            ]
        ),
        html.Div(
            style={
                'background': COLOR_SCHEME['card_bg'],
                'padding': '1.5rem',
                'borderRadius': '8px',
                'marginBottom': '2rem',
                'border': f'1px solid {COLOR_SCHEME["border"]}',
                'position': 'relative'
            },
            children=[
                html.Div(
                    style={
                        'position': 'absolute',
                        'top': 0,
                        'right': 0,
                        'width': '80px',
                        'height': '80px',
                        'background': f'linear-gradient(45deg, {COLOR_SCHEME["progress"]}30, transparent)',
                        'borderRadius': '0 8px 0 50px'
                    }
                ),
                html.H3(
                    '⏳ 供暖季进度',
                    style={
                        'color': COLOR_SCHEME['progress'],
                        'marginBottom': '1rem',
                        'position': 'relative',
                        'zIndex': 1
                    }
                ),
                html.Div(
                    style={
                        'height': '12px',
                        'backgroundColor': COLOR_SCHEME['border'],
                        'borderRadius': '6px',
                        'position': 'relative',
                        'overflow': 'hidden'
                    },
                    children=[
                        html.Div(
                            style={
                                'width': f"{current_data['供暖进度'] * 100}%",
                                'height': '100%',
                                'background': f'linear-gradient(90deg, {COLOR_SCHEME["progress"]}, {COLOR_SCHEME["accent"]})',
                                'borderRadius': '6px',
                                'transition': 'width 0.5s ease',
                                'boxShadow': 'inset 0 2px 4px rgba(255,255,255,0.1)'
                            }
                        )
                    ]
                ),
                html.Div(
                    style={
                        'display': 'flex',
                        'justifyContent': 'space-between',
                        'marginTop': '1rem',
                        'color': COLOR_SCHEME['secondary'],
                        'fontSize': '0.9rem'
                    },
                    children=[
                        html.Span("❄️ 开始日期：2024-11-15"),
                        html.Span(f"🔥 当前进度：{current_data['供暖进度'] * 100:.1f}%"),
                        html.Span("🌱 结束日期：2025-03-15")
                    ]
                )
            ]
        ),
        html.Div(
            style={
                'background': COLOR_SCHEME['card_bg'],
                'padding': '1.5rem',
                'borderRadius': '8px',
                'border': f'1px solid {COLOR_SCHEME["border"]}',
                'boxShadow': '0 8px 24px rgba(0,0,0,0.3)'
            },
            children=[
                dcc.Graph(
                    figure=create_timeline_chart(full_df),
                    config={'responsive': True}
                )
            ]
        )
    ]
)
if __name__ == '__main__':
    app.run_server(debug=True)
